wayland: Commit surface from cairo context
authorJonas Ådahl <jadahl@gmail.com>
Thu, 17 Sep 2020 15:35:35 +0000 (17:35 +0200)
committerJonas Ådahl <jadahl@gmail.com>
Thu, 17 Sep 2020 15:35:35 +0000 (17:35 +0200)
In order to make the cairo renderer/context behave more similar to how
the OpenGL and Vulkan renderer/context behaves, request a frame callback
and commit in the end frame vfunc.

This means the end frame vfunc in cairo does

 * attach buffer
 * request frame callback
 * sync surface state
 * commit

Where as e.g. the OpenGL version of the same flow does

 * attach buffer
 * request frame callback
 * sync surface state
 * eglSwapBuffers()

where eglSwapBuffers() indirectly calls wl_surface_commit().

gdk/wayland/gdkcairocontext-wayland.c
gdk/wayland/gdkprivate-wayland.h
gdk/wayland/gdksurface-wayland.c

index bb28ada46f4507ed57fb5054d27ce01c30696ab9..d0fc54d0b0fd64cc4b43a4142d20ac5be33f235d 100644 (file)
@@ -23,6 +23,7 @@
 #include "gdkprivate-wayland.h"
 
 #include "gdkinternals.h"
+#include "gdkprofilerprivate.h"
 
 static const cairo_user_data_key_t gdk_wayland_cairo_context_key;
 static const cairo_user_data_key_t gdk_wayland_cairo_region_key;
@@ -180,6 +181,10 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
 
   gdk_wayland_surface_attach_image (surface, self->paint_surface, painted);
   gdk_wayland_surface_sync (surface);
+  gdk_wayland_surface_request_frame (surface);
+
+  gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
+  gdk_wayland_surface_commit (surface);
 
   gdk_wayland_cairo_context_surface_clear_region (self->paint_surface);
   self->paint_surface = NULL;
index dc7c4848a2dfbcf5a2f2480e041d0eb70f108645..db45a07c085c9bc5fcc9e98c11df09d90bd00918 100644 (file)
@@ -94,6 +94,7 @@ guint      _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
                                                      guint             *next_image_delay);
 
 void       gdk_wayland_surface_sync (GdkSurface *surface);
+void       gdk_wayland_surface_commit (GdkSurface *surface);
 void       gdk_wayland_surface_request_frame (GdkSurface *surface);
 void            gdk_wayland_surface_attach_image           (GdkSurface           *surface,
                                                             cairo_surface_t      *cairo_surface,
index 7ac0a78263369bd086521a78c2e18a1e7ded3f9e..bda30ae39ca5b9434c22bcad55b7a060a3d1ef5b 100644 (file)
@@ -95,7 +95,6 @@ struct _GdkWaylandSurface
 
   unsigned int initial_configure_received : 1;
   unsigned int mapped : 1;
-  unsigned int pending_commit : 1;
   unsigned int awaiting_frame : 1;
   unsigned int awaiting_frame_frozen : 1;
   unsigned int is_drag_surface : 1;
@@ -615,30 +614,20 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
   impl->awaiting_frame = TRUE;
 }
 
+void
+gdk_wayland_surface_commit (GdkSurface *surface)
+{
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+  wl_surface_commit (impl->display_server.wl_surface);
+}
+
 static void
 on_frame_clock_after_paint (GdkFrameClock *clock,
                             GdkSurface    *surface)
 {
   GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
-  if (impl->pending_commit && surface->update_freeze_count == 0)
-    {
-      gdk_wayland_surface_request_frame (surface);
-
-      /* From this commit forward, we can't write to the buffer,
-       * it's "live".  In the future, if we need to stage more changes
-       * we have to allocate a new staging buffer and draw to it instead.
-       *
-       * Our one saving grace is if the compositor releases the buffer
-       * before we need to stage any changes, then we can take it back and
-       * use it again.
-       */
-      gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
-      wl_surface_commit (impl->display_server.wl_surface);
-
-      impl->pending_commit = FALSE;
-    }
-
   if (impl->awaiting_frame &&
       impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
     {
@@ -804,7 +793,6 @@ gdk_wayland_surface_attach_image (GdkSurface           *surface,
       cairo_region_get_rectangle (damage, i, &rect);
       wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
     }
-  impl->pending_commit = TRUE;
 }
 
 void
@@ -2789,7 +2777,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
   unset_transient_for_exported (surface);
 
   _gdk_wayland_surface_clear_saved_size (surface);
-  impl->pending_commit = FALSE;
   impl->mapped = FALSE;
 }